/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pro.unal.edu.sink.write;

import java.awt.Color;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import pro.unal.edu.datasource.BMPImage;
import pro.unal.edu.datasource.MyImage;

/**
 * @author Carlos Eduardo Bernal Cárdenas
 * @version 1.0
 * @created 30-ago-2011
 */
public class BMPWriter {

    private static FileOutputStream fo;
    private static byte[] bufferImage;

    public static void save(String nameImage, MyImage image) {
        bufferImage = new byte[((BMPImage) image).getFileSize()];
        try {
            fo = new FileOutputStream(nameImage);
            writeBitmapInfoHeader(image);
            writeBitmapHeader(image);
            writeBitmap(image);
            //convertImage(image);
            fo.write(bufferImage);
            fo.close();
        } catch (Exception saveEx) {
            Logger.getLogger(BMPWriter.class.getName()).log(Level.INFO, "Error writing the image");
            saveEx.printStackTrace();
        }
    }

    private static void writeBitmapInfoHeader(MyImage image) throws IOException {
        BMPImage bmp = (BMPImage) image;
        /**Begining of Information Header 14 bytes**/
        //2 bytes for signature
        bufferImage[0] = Byte.parseByte(((int) bmp.getType().charAt(0)) + "");
        bufferImage[1] = Byte.parseByte(((int) bmp.getType().charAt(1)) + "");
        //4 bytes for filesize        
        bufferImage[2] = (byte) (bmp.getFileSize());
        bufferImage[3] = (byte) (bmp.getFileSize() >>> 8);
        bufferImage[4] = (byte) (bmp.getFileSize() >>> 16);
        bufferImage[5] = (byte) (bmp.getFileSize() >>> 24);
        //4 bytes for reserved
        bufferImage[6] = (byte) (bmp.getReserved());
        bufferImage[7] = (byte) (bmp.getReserved() >>> 8);
        bufferImage[8] = (byte) (bmp.getReserved() >>> 16);
        bufferImage[9] = (byte) (bmp.getReserved() >>> 24);
        //4 bytes for dataOffset
        bufferImage[10] = (byte) (bmp.getOffset());
        bufferImage[11] = (byte) (bmp.getOffset() >>> 8);
        bufferImage[12] = (byte) (bmp.getOffset() >>> 16);
        bufferImage[13] = (byte) (bmp.getOffset() >>> 24);
        /**End of Information Header**/
    }

    private static void writeBitmapHeader(MyImage image) {
        BMPImage bmp = (BMPImage) image;
        /**Begining of Header 40 bytes**/
        //4 bytes for sizeInfoHeader
        bufferImage[14] = (byte) (bmp.getSizeInfoHeader());
        bufferImage[15] = (byte) (bmp.getSizeInfoHeader() >>> 8);
        bufferImage[16] = (byte) (bmp.getSizeInfoHeader() >>> 16);
        bufferImage[17] = (byte) (bmp.getSizeInfoHeader() >>> 24);
        //4 bytes for width
        bufferImage[18] = (byte) (bmp.getWidth());
        bufferImage[19] = (byte) (bmp.getWidth() >>> 8);
        bufferImage[20] = (byte) (bmp.getWidth() >>> 16);
        bufferImage[21] = (byte) (bmp.getWidth() >>> 24);
        //4 bytes for height
        bufferImage[22] = (byte) (bmp.getHeight());
        bufferImage[23] = (byte) (bmp.getHeight() >>> 8);
        bufferImage[24] = (byte) (bmp.getHeight() >>> 16);
        bufferImage[25] = (byte) (bmp.getHeight() >>> 24);
        //2 bytes for planes
        bufferImage[26] = (byte) (bmp.getPlanes());
        bufferImage[27] = (byte) (bmp.getPlanes() >>> 8);
        //2 bytes for bitCount
        bufferImage[28] = (byte) (bmp.getBitPerPixel());
        bufferImage[29] = (byte) (bmp.getBitPerPixel() >>> 8);
        //4 bytes for compression
        bufferImage[30] = (byte) (bmp.getCompression());
        bufferImage[31] = (byte) (bmp.getCompression() >>> 8);
        bufferImage[32] = (byte) (bmp.getCompression() >>> 16);
        bufferImage[33] = (byte) (bmp.getCompression() >>> 24);
        //4 bytes for imageSize
        bufferImage[34] = (byte) (bmp.getImageSize());
        bufferImage[35] = (byte) (bmp.getImageSize() >>> 8);
        bufferImage[36] = (byte) (bmp.getImageSize() >>> 16);
        bufferImage[37] = (byte) (bmp.getImageSize() >>> 24);
        //4 bytes for xPixels
        bufferImage[38] = (byte) (bmp.getxPixelsPerM());
        bufferImage[39] = (byte) (bmp.getxPixelsPerM() >>> 8);
        bufferImage[40] = (byte) (bmp.getxPixelsPerM() >>> 16);
        bufferImage[41] = (byte) (bmp.getxPixelsPerM() >>> 24);
        //4 bytes for yPixels
        bufferImage[42] = (byte) (bmp.getyPixelsPerM());
        bufferImage[43] = (byte) (bmp.getyPixelsPerM() >>> 8);
        bufferImage[44] = (byte) (bmp.getyPixelsPerM() >>> 16);
        bufferImage[45] = (byte) (bmp.getyPixelsPerM() >>> 24);
        //4 bytes for colorsUsed
        bufferImage[46] = (byte) (bmp.getColorsUsed());
        bufferImage[47] = (byte) (bmp.getColorsUsed() >>> 8);
        bufferImage[48] = (byte) (bmp.getColorsUsed() >>> 16);
        bufferImage[49] = (byte) (bmp.getColorsUsed() >>> 24);
        //4 bytes for ImportantColors
        bufferImage[50] = (byte) (bmp.getColorsImportant());
        bufferImage[51] = (byte) (bmp.getColorsImportant() >>> 8);
        bufferImage[52] = (byte) (bmp.getColorsImportant() >>> 16);
        bufferImage[53] = (byte) (bmp.getColorsImportant() >>> 24);
        /**End of Header**/
    }

    private static void writeBitmap(MyImage image) {
        BMPImage bmp = (BMPImage) image;
        int i = 54;
        int x = 1;
        int grow = 3;
        int filter = 0;
        if (bmp.getBitPerPixel() == 32) {
            grow = 4;
        }
        if (bmp.getBitPerPixel() == 24) {
            grow = 3;
        }
        /**Begining of Information**/
        Color[][] colors = bmp.getDataImageColor();
        for (int k = 0; k < colors[0].length; k++) {
            for (int j = 0; j < colors.length; j++) {
//                System.out.println("k:"+k+"  j:"+j);
                int r = colors[j][k].getRed();
                int g = colors[j][k].getGreen();
                int b = colors[j][k].getBlue();

                bufferImage[i] = (byte) b;
                i++;
                bufferImage[i] = (byte) g;
                i++;
                bufferImage[i] = (byte) r;
                i++;
                if (bmp.getBitPerPixel() == 32) {
                    bufferImage[i] = (byte) 0;
                    i++;
                }
                if ((x % bmp.getWidth()) == 0) {
                    if ((bmp.getWidth()) % 4 != 0) {
                        i += (4 - (3 * (bmp.getWidth()) % 4));
                    }
                }
                x++;
            }
        }
        System.out.println("compression: " + bmp.getxPixelsPerM());
        System.out.println("compression: " + bmp.getyPixelsPerM());
        /**End of Information**/
    }

    private static void convertImage(MyImage image) {
    }
}
